package com.forum.auth.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Logger;
import feign.Response;
import feign.codec.Decoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
 * Feign客户端配置
 */
@Configuration
public class FeignConfig {
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 设置Feign客户端的日志级别为FULL，便于调试
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    /**
     * 自定义解码器，能够处理包装在对象中的原始类型值
     */
    @Bean
    public Decoder feignDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {
        return new ResponseEntityDecoder(new CustomResponseDecoder(messageConverters));
    }
    
    /**
     * 自定义响应解码器，处理包装在对象中的值
     */
    public class CustomResponseDecoder extends SpringDecoder {
        
        public CustomResponseDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {
            super(messageConverters);
        }
        
        @Override
        public Object decode(Response response, Type type) throws IOException {
            // 如果响应类型是Long、Integer等原始类型包装类，尝试从包装的JSON中提取
            if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(Boolean.class)) {
                try {
                    // 读取响应体
                    InputStream inputStream = response.body().asInputStream();
                    String responseBody = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
                    System.out.println("原始响应体: " + responseBody);
                    
                    // 解析JSON
                    JsonNode jsonNode = objectMapper.readTree(responseBody);
                    
                    // 尝试读取不同的字段名，兼容不同的响应格式
                    if (jsonNode.has("data")) {
                        JsonNode dataNode = jsonNode.get("data");
                        if (type.equals(Long.class)) {
                            if (dataNode.isNumber()) {
                                return dataNode.asLong();
                            } else if (dataNode.isTextual()) {
                                return Long.parseLong(dataNode.asText());
                            }
                        } else if (type.equals(Integer.class)) {
                            return dataNode.asInt();
                        } else if (type.equals(Boolean.class)) {
                            return dataNode.asBoolean();
                        }
                    } else if (jsonNode.has("userId")) {
                        // 特殊情况，如果直接返回了包含userId的对象
                        return jsonNode.get("userId").asLong();
                    } else if (jsonNode.has("id")) {
                        // 或者返回了包含id的对象
                        return jsonNode.get("id").asLong();
                    } else if (jsonNode.has("code") && jsonNode.has("message")) {
                        // 如果是标准响应格式
                        if (jsonNode.has("data")) {
                            return extractValue(jsonNode.get("data"), type);
                        }
                    }
                    
                    // 尝试其他可能的解析方法
                    return extractValue(jsonNode, type);
                    
                } catch (Exception e) {
                    System.err.println("自定义解码器处理失败: " + e.getMessage());
                    e.printStackTrace();
                    // 出现异常时回退到默认解码器
                }
            }
            
            // 对于其他类型或解析失败的情况，使用默认解码器
            return super.decode(response, type);
        }
        
        /**
         * 从JsonNode中提取指定类型的值
         */
        private Object extractValue(JsonNode node, Type type) {
            if (type.equals(Long.class)) {
                if (node.isNumber()) {
                    return node.asLong();
                } else if (node.isTextual()) {
                    try {
                        return Long.parseLong(node.asText());
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }
            } else if (type.equals(Integer.class)) {
                if (node.isNumber()) {
                    return node.asInt();
                } else if (node.isTextual()) {
                    try {
                        return Integer.parseInt(node.asText());
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }
            } else if (type.equals(Boolean.class)) {
                if (node.isBoolean()) {
                    return node.asBoolean();
                } else if (node.isTextual()) {
                    return Boolean.parseBoolean(node.asText());
                }
            }
            return null;
        }
    }
} 